package cn.hengzhu.main_manager.utils.shiro.realm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import cn.hengzhu.main_manager.repository.dao.ManagePermissionMapper;
import cn.hengzhu.main_manager.repository.dao.ManageRolesMapper;
import cn.hengzhu.main_manager.repository.dao.ManageUserMapper;
import cn.hengzhu.main_manager.repository.domain.ManagePermission;
import cn.hengzhu.main_manager.repository.domain.ManagePermissionExample;
import cn.hengzhu.main_manager.repository.domain.ManageRoles;
import cn.hengzhu.main_manager.repository.domain.ManageUser;
import cn.hengzhu.main_manager.utils.Md5Util;

/**
 * 实现一个Realm,用来访问安全数据
 * @author Administrator
 *
 */
public class MyRealm extends AuthorizingRealm {
	@Autowired
	private ManageUserMapper manageUserMapper;
	@Autowired
	private ManagePermissionMapper managePermissionMapper;
	@Autowired
	private ManageRolesMapper manageRolesMapper;

	// 返回身份认证信息
	// 6）自定义 Realm 的方法, 从数据库中获取对应的记录, 返回给 Shiro.
	// 入门中使用的是Shiro自带的IniRealm，IniRealm从ini配置文件中读取用户的信息，大部分情况下需要从系统的数据库中读取用户信息，所以需要自定义realm。
	// 实际上需要继承 org.apache.shiro.realm.AuthenticatingRealm 类
	// 实现 doGetAuthenticationInfo(AuthenticationToken) 方法.
	// 7）由 shiro 完成对密码的比对.
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取用户名
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		String username = usernamePasswordToken.getUsername();
		// 通过用户名查询用户--除了查询员工信息,还要查询对应角色信息
		
		
		ManageUser manageUser = manageUserMapper.findByLoginName(username);
		// 进行判断
		if (manageUser==null) {
			// 账号不存在
			throw new UnknownAccountException();
		} else {
			Object principal = manageUser;// 身份,用户名或者用户都可以
			Object hashedCredentials = manageUser.getPassWord();
			ByteSource credentialsSalt = ByteSource.Util.bytes(Md5Util.SALT);
			// .................
			// 返回用户信息
			return new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, getName());
		}
	}

	// 返回用户权限信息
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		// 获取用户名 //通过用户名查询用户
		ManageUser manageUser = (ManageUser) principalCollection.getPrimaryPrincipal();
		// 通过用户查询拥有的权限,并且把权限返回给框架让框架进行权限判断
		Integer managerId = manageUser.getManagerId();
		ManageUser selectByPrimaryKey = manageUserMapper.selectByPrimaryKey(managerId);
		Integer roleId = selectByPrimaryKey.getRoleId();
		ManageRoles selectByPrimaryKey2 = manageRolesMapper.selectByPrimaryKey(roleId);
		String permissions = selectByPrimaryKey2.getPermissions();
		List<String> asList = Arrays.asList(permissions.split(","));

		List<Integer> idInteger = asList.stream().map(Integer::parseInt).collect(Collectors.toList());
		ManagePermissionExample example = new ManagePermissionExample();
		example.createCriteria().andIdIn(idInteger);
		List<ManagePermission> permissionList = managePermissionMapper.selectByExample(example);

		// 把权限的Sn返回框架
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Collection<String> permissionSns = new ArrayList<String>();
		permissionList.stream().forEach(a -> {
			if (a != null) {
				permissionSns.add(a.getSn());
			}
		});
		
		info.addStringPermissions(permissionSns);
		return info;
	}


}
